import React, { useRef, useState, useEffect } from 'react';
import { Select, Tooltip, Spin, Modal, Switch, message } from 'antd';
import { ReloadOutlined, BulbOutlined, BulbFilled } from '@ant-design/icons';
import { EditorSettings } from '@/types/editor';
import styles from './CodeEditor.module.css';
import { registerCompletionProviders, getCompletionEditorOptions } from './codeCompletion';
import Editor, { loader } from '@monaco-editor/react';
import { PROGRAMMING_LANGUAGE_OPTIONS, MONACO_LANGUAGE_MAP } from '@/utils/mappings';
import { useAuthStore } from '@/store/useAuthStore';
import { ErrorInfo } from '@/utils/errorParser';
// 扩展Window接口以包含monaco属性
declare global {
  interface Window {
    monaco: any;
  }
}

// 配置 Monaco Editor 加载器
loader.config({
  paths: {
    //vs: 'https://cdn.bootcdn.net/ajax/libs/monaco-editor/0.52.2/min/vs/'
    vs: '/monaco-editor/min/vs'  // 指向本地托管的 Monaco Editor 文件
  },
  'vs/nls': {
    availableLanguages: {
      '*': 'zh-cn'  // 设置中文语言包
    }
  }
});

// 语言选项
const languageOptions = PROGRAMMING_LANGUAGE_OPTIONS;

// 语言映射 - 从后端语言名称到Monaco编辑器语言ID
const languageMapping = MONACO_LANGUAGE_MAP;

interface CodeEditorProps {
  value: string;
  language: string;
  editorSettings: EditorSettings;
  onChange: (value: string) => void;
  onLanguageChange: (value: string) => void;
  problemId?: string; // 用来生成存储代码的键
  errors?: ErrorInfo[]; // 错误信息数组
}

const CodeEditor: React.FC<CodeEditorProps> = ({
  value,
  language,
  editorSettings,
  onChange,
  onLanguageChange,
  problemId = '',
  errors = [],
}) => {
  const { user } = useAuthStore();
  const editorRef = useRef<any>(null);
  const [editorLoaded, setEditorLoaded] = useState(false);
  const [showClearConfirm, setShowClearConfirm] = useState(false);
  const [completionEnabled, setCompletionEnabled] = useState(() => {
    const userId = user?.id?.toString() || 'anonymous';
    const saved = localStorage.getItem(`editor_completion_enabled_${userId}`);
    return saved ? saved === 'true' : false;
  });
  const [isEditorReady, setIsEditorReady] = useState(false);
  const [errorMarkers, setErrorMarkers] = useState<any[]>([]);
  
  // 添加一个effect来确保编辑器加载状态正确
  useEffect(() => {
    // 如果我们有editorRef但isEditorReady还是false，则设置为true
    if (editorRef.current && !isEditorReady) {
      setIsEditorReady(true);
    }
  }, [editorRef.current, isEditorReady]);

  // 设置错误标记
  useEffect(() => {
    if (editorRef.current && window.monaco && errors.length > 0) {
      // 清除之前的错误标记
      window.monaco.editor.setModelMarkers(editorRef.current.getModel(), 'compiler', []);
      
      // 创建新的错误标记
      const markers = errors.map((error) => ({
        startLineNumber: error.line,
        startColumn: error.column || 1,
        endLineNumber: error.line,
        endColumn: error.column || 1,
        message: error.message,
        severity: error.severity === 'error' ? window.monaco.MarkerSeverity.Error : window.monaco.MarkerSeverity.Warning,
        // 添加更多标记属性以确保tooltip正确显示
        source: 'compiler',
        code: error.severity === 'error' ? 'E001' : 'W001',
        relatedInformation: []
      }));
      
      // 设置错误标记
      window.monaco.editor.setModelMarkers(editorRef.current.getModel(), 'compiler', markers);
      setErrorMarkers(markers);
      
      // 确保编辑器滚动到第一个错误位置
      if (markers.length > 0) {
        const firstError = markers[0];
        editorRef.current.revealLineInCenter(firstError.startLineNumber);
      }
    } else if (editorRef.current && window.monaco && errors.length === 0) {
      // 清除所有错误标记
      window.monaco.editor.setModelMarkers(editorRef.current.getModel(), 'compiler', []);
      setErrorMarkers([]);
    }
  }, [errors, editorRef.current, window.monaco]);
  
  // 生成本地存储的键
  const getStorageKey = () => {
    const userId = user?.id?.toString() || 'anonymous';
    return `code_${problemId}_${language}_${userId}`;
  };

  // 保存代码到本地存储
  const handleCodeChange = (value: string | undefined) => {
    if (value !== undefined) {
      onChange(value);
      localStorage.setItem(getStorageKey(), value);
    }
  };

  // 清除缓存的代码
  const handleClearCache = () => {
    setShowClearConfirm(true);
  };

  // 确认清除缓存
  const confirmClearCache = () => {
    if (problemId) {
      localStorage.removeItem(getStorageKey());
      onChange('');
      setShowClearConfirm(false);
    }
  };

  // 取消清除缓存
  const cancelClearCache = () => {
    setShowClearConfirm(false);
  };

  // 切换代码补全功能
  const toggleCompletion = (checked: boolean) => {
    try {
      setCompletionEnabled(checked);
      const userId = user?.id?.toString() || 'anonymous';
      localStorage.setItem(`editor_completion_enabled_${userId}`, checked.toString());
      
      if (editorRef.current && window.monaco) {
        // 更新编辑器选项
        editorRef.current.updateOptions(getCompletionEditorOptions(checked));
        
        // 重新注册代码补全提供程序
        registerCompletionProviders(window.monaco, checked);
      }
    } catch (error) {
      console.error('切换代码补全失败:', error);
      message.error('切换代码补全失败');
      setCompletionEnabled(false);
    }
  };

  // 初始化编辑器
  const handleEditorDidMount = (editor: any, monaco: any) => {
    console.log("开始初始化编辑器")
    editorRef.current = editor;
    window.monaco = monaco;
    
    // 确保tooltip有最高z-index
    const ensureTooltipZIndex = () => {
      const tooltips = document.querySelectorAll('.monaco-editor .monaco-hover');
      tooltips.forEach((tooltip: any) => {
        if (tooltip) {
          tooltip.style.zIndex = '9999';
          tooltip.style.position = 'fixed';
        }
      });
    };
    
    // 监听DOM变化，确保tooltip的z-index
    const observer = new MutationObserver(ensureTooltipZIndex);
    observer.observe(document.body, { childList: true, subtree: true });
    
    // 基本编辑器配置
    const baseOptions = {
      tabSize: editorSettings.tabSize,
      fontSize: editorSettings.fontSize,
      fontFamily: editorSettings.fontFamily,
      automaticLayout: true,
      minimap: { enabled: false },
      scrollBeyondLastLine: false,
      lineNumbers: 'on',
      wordWrap: 'on',
      lineNumbersMinChars: 3,
      folding: false,
      glyphMargin: false,
      renderLineHighlight: 'none',
      contextmenu: false,
      links: false,
      useWorker: false,
      // 修复tooltip被遮挡的问题
      hover: {
        enabled: true,
        delay: 300,
        sticky: true,
        above: true // 优先在元素上方显示
      },
      // 确保编辑器有足够的空间显示tooltip
      scrollbar: {
        vertical: 'visible',
        horizontal: 'visible',
        verticalScrollbarSize: 14,
        horizontalScrollbarSize: 14
      }
    };

    // 合并代码补全选项
    const editorOptions = {
      ...baseOptions,
      ...getCompletionEditorOptions(completionEnabled)
    };

    editor.updateOptions(editorOptions);
    
    // 注册代码补全提供程序
    registerCompletionProviders(monaco, completionEnabled);
    
    setEditorLoaded(true);
    setIsEditorReady(true);
    console.log("加载完成, 请开始你的表演!");

    // 在编辑器加载完成后加载保存的代码
    const savedCode = localStorage.getItem(getStorageKey());
    if (savedCode && savedCode !== value) {
      onChange(savedCode);
    }
  };

  return (
    <div className={styles.editorContent}>
      <div className={styles.editorToolbar}>
        <div className={styles.toolbarLeft}>
          <Select
            className={styles.languageSelector}
            value={language}
            onChange={onLanguageChange}
            options={languageOptions}
            size="small"
          />
        </div>
        <div className={styles.toolbarRight}>
          <Tooltip title={completionEnabled ? "关闭代码补全" : "开启代码补全"}>
            <div className={styles.completionToggle}>
              <Switch 
                size="small" 
                checked={completionEnabled} 
                onChange={toggleCompletion}
                checkedChildren={<BulbFilled />}
                unCheckedChildren={<BulbOutlined />}
              />
            </div>
          </Tooltip>
          <Tooltip title="清除缓存的代码">
            <ReloadOutlined 
              className={styles.refreshButton} 
              onClick={handleClearCache}
            />
          </Tooltip>
        </div>
      </div>
      <div className={styles.editorWrapper}>
        {!isEditorReady && (
          <div style={{ height: "100%", display: "flex", alignItems: "center", justifyContent: "center" }}>
            <Spin size="large">
              <div style={{ height: 80, width: 80 }} />
            </Spin>
          </div>
        )}
        <Editor
          height="100%"
          value={value}
          language={languageMapping[language] || 'cpp'}
          onChange={handleCodeChange}
          theme={editorSettings.theme === 'dark' ? 'vs-dark' : 'vs-light'}
          onMount={handleEditorDidMount}
          options={{
            fontSize: editorSettings.fontSize,
            fontFamily: editorSettings.fontFamily,
            tabSize: editorSettings.tabSize,
            minimap: { enabled: false },
            scrollBeyondLastLine: false,
            lineNumbers: 'on',
            wordWrap: 'on',
            folding: false
          }}
          className={!isEditorReady ? styles.hiddenEditor : ''}
        />
      </div>

      <Modal
        title="确认清除"
        open={showClearConfirm}
        onOk={confirmClearCache}
        onCancel={cancelClearCache}
        okText="确认"
        cancelText="取消"
      >
        <p>确定要清除当前缓存的代码吗？此操作无法恢复。</p>
      </Modal>
    </div>
  );
};

export default CodeEditor
